package org.example.atomictest;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.example.utils.Sleeper;

import java.util.concurrent.atomic.AtomicMarkableReference;

/**
 * @author zhengdp
 * @Description
 * @Date 2022/11/20 19:23
 * @Created by zhengdp
 */
@Slf4j(topic = "c.AtomicMarkableReferenceTest")
public class AtomicMarkableReferenceTest {

    public static void main(String[] args) {
        GarbageBag bar = new GarbageBag("装满了垃圾");

        // 参数2 mark 可以看作是一个标记，表示垃圾袋是否满了
        AtomicMarkableReference<GarbageBag> ref = new AtomicMarkableReference<>(bar,true);

        log.info("Start ....");
        GarbageBag prev = ref.getReference();
        log.info(prev.toString());

        // 保洁阿姨更换了垃圾袋
        new Thread(() -> {
            log.info("start ...");
            bar.setDesc("空垃圾袋");
            ref.compareAndSet(bar,bar,true,false);
            log.info(bar.toString());
        },"保洁阿姨").start();

        //更换垃圾袋
        Sleeper.sleep(1000);
        log.info("想要更换一只新的垃圾袋？");
        // 如果标记被更改过，那么这个更换操作就会失败
        boolean success = ref.compareAndSet(prev,new GarbageBag("空垃圾袋"),true,false);
        log.info("是否更换？: {}",success);
        log.info(ref.getReference().toString());

    }

    @Data
    @AllArgsConstructor
    static class GarbageBag {
        String desc;

    }
}
